<script setup>
import { ref, computed, onUnmounted, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { ResultViews, line, phase, point } from './components'
import {
	binplotPhase, // 二元相图
	ternplotPhase, // 三元相图
	lineTempRange, // 温度范围线
	lineCompRange, // 成分范围线
	equilibriumEndpoint, //  点图
} from '@/api/test'

// 图表类型选项
const chartTypes = [
	{ label: '二元计算', value: 'binary' },
	{ label: '三元计算', value: 'ternary' },
]

const chartModel = [
	{ label: '点计算', value: 'point' },
	{ label: '线计算', value: 'line' },
	{ label: '相图计算', value: 'phase' },
]

// 当前选择的图表类型
const selectedChartType = ref('binary')

const selectedChartModel = ref('point')

// 左侧面板宽度控制
const leftPanelWidth = ref(400) // 默认宽度
const minLeftWidth = 300 // 最小宽度
const maxLeftWidth = 800 // 最大宽度
const isDragging = ref(false)

// 拖动相关状态
const startX = ref(0)
const startWidth = ref(0)

// 开始拖动
const startDrag = (e) => {
	isDragging.value = true
	startX.value = e.clientX
	startWidth.value = leftPanelWidth.value

	// 添加全局事件监听
	document.addEventListener('mousemove', onDrag)
	document.addEventListener('mouseup', stopDrag)

	// 添加全局样式
	document.body.classList.add('dragging')

	// 防止文本选择
	e.preventDefault()
}

// 拖动中
const onDrag = (e) => {
	if (!isDragging.value) return

	const deltaX = e.clientX - startX.value
	const newWidth = startWidth.value + deltaX

	// 限制宽度范围
	if (newWidth >= minLeftWidth && newWidth <= maxLeftWidth) {
		leftPanelWidth.value = newWidth
	}
}

// 停止拖动
const stopDrag = () => {
	isDragging.value = false
	document.removeEventListener('mousemove', onDrag)
	document.removeEventListener('mouseup', stopDrag)

	// 移除全局样式
	document.body.classList.remove('dragging')
}

// 组件卸载时清理事件监听
onUnmounted(() => {
	document.removeEventListener('mousemove', onDrag)
	document.removeEventListener('mouseup', stopDrag)

	// 清理全局样式
	document.body.classList.remove('dragging')

	// 清理可能存在的 blob URL 对象以释放内存
	if (resultImage.value && resultImage.value.startsWith('blob:')) {
		URL.revokeObjectURL(resultImage.value)
	}
})

const isComponent = computed(() => {
	switch (selectedChartModel.value) {
		case 'phase':
			return phase
		case 'line':
			return line
		case 'point':
			return point
		default:
			return phase
	}
})

const resultTitle = computed(() => {
	const type = selectedChartType.value === 'binary' ? '二元' : '三元'
	const model = chartModel.find(
		(item) => item.value === selectedChartModel.value
	)
	return type + model.label
})

const isLoading = ref(false)
const resultImage = ref('')
const resultData = ref(null) // 新增：用于存储点图的表格数据
const resultType = ref('image') // 新增：结果类型，'image' 或 'table'

const timer = ref(new Date().getTime())

// API 调用映射表
const apiMap = {
	'binary-phase': binplotPhase,
	'ternary-phase': ternplotPhase,
	temp_range: lineTempRange,
	comp_range: lineCompRange,
	point: equilibriumEndpoint,
}

// 错误消息映射表
const errorMessages = {
	'binary-phase': '二元相图生成失败，请检查输入！',
	'ternary-phase': '三元相图生成失败，请检查输入！',
	temp_range: '温度范围线图生成失败，请检查输入！',
	comp_range: '成分范围线图生成失败，请检查输入！',
	point: '点图计算失败，请检查输入！',
}

// 根据图表类型选择对应的提交函数
const onSubmit = async (formData) => {
	const { model, type, mode } = formData
	let apiKey = '' // 将 apiKey 声明提前到 try 块外

	isLoading.value = true
	try {
		// 清理参数，移除前端特有的字段
		const params = { ...formData }
		delete params.model
		delete params.type
		delete params.mode

		let res = null

		// 确定API调用键值
		if (type === 'binary' && model === 'phase') {
			apiKey = 'binary-phase'
		} else if (type === 'ternary' && model === 'phase') {
			apiKey = 'ternary-phase'
		} else if (model === 'line') {
			// 线图根据 mode 参数确定具体的 API
			apiKey = mode || 'temp_range' // 默认为 temp_range
		} else if (model === 'point') {
			apiKey = 'point'
		} else {
			throw new Error(
				`不支持的图表类型: ${type}-${model}${mode ? '-' + mode : ''}`
			)
		}

		// 统一调用API
		const apiFunction = apiMap[apiKey]
		if (!apiFunction) {
			throw new Error(`找不到对应的API函数: ${apiKey}`)
		}

		res = await apiFunction(params)

		// 处理返回数据 - 区分点图和其他图表
		if (model === 'point') {
			// 点图返回的是数据对象，需要显示为表格
			if (res && res.code === 200) {
				resultData.value = res.data
				resultType.value = 'table'
				resultImage.value = '' // 清空图片
			} else {
				throw new Error('点图API返回数据格式不正确')
			}
		} else {
			// 其他图表返回base64格式的图片
			if (res && res.code === 200 && res.data && res.data.data) {
				// 处理base64格式的图片数据
				const base64Image = res.data.data
				resultImage.value = `data:image/png;base64,${base64Image}`
				resultType.value = 'image'
				resultData.value = null // 清空表格数据
			} else {
				throw new Error('API返回数据格式不正确')
			}
		}

		isLoading.value = false
	} catch (error) {
		const errorMessage = errorMessages[apiKey] || '图表生成失败，请检查输入！'
		console.error(`${apiKey || 'unknown'}提交错误:`, error)
		ElMessage.error(errorMessage)
		isLoading.value = false
		throw error
	}
}

// 图表类型改变时清空结果图片
const onChartTypeChange = () => {
	// 清理可能存在的 blob URL 对象以释放内存
	if (resultImage.value && resultImage.value.startsWith('blob:')) {
		URL.revokeObjectURL(resultImage.value)
	}
	if (
		selectedChartType.value === 'ternary' &&
		selectedChartModel.value === 'line'
	) {
		selectedChartModel.value = 'point'
	}

	// 清理之前的结果
	resultImage.value = ''
	resultData.value = null
	resultType.value = 'image'
	// 重置加载状态
	isLoading.value = false
	// 更新时间戳强制组件重新渲染
	timer.value = new Date().getTime()
}

const onChartModelChange = (value) => {
	// 清理可能存在的 blob URL 对象以释放内存
	if (resultImage.value && resultImage.value.startsWith('blob:')) {
		URL.revokeObjectURL(resultImage.value)
	}

	selectedChartModel.value = value
	// 清理之前的结果
	resultImage.value = ''
	resultData.value = null
	resultType.value = 'image'
	// 重置加载状态
	isLoading.value = false
	// 更新时间戳强制组件重新渲染
	timer.value = new Date().getTime()
}
</script>

<template>
	<div class="line-graph-container">
		<!-- 图表类型选择器 -->
		<div class="chart-type-selector">
			<div class="chart-type-selector-left">
				<div class="selector-label">
					<i class="chart-icon"></i>
					图表类型
				</div>
				<el-select
					v-model="selectedChartType"
					placeholder="请选择图表类型"
					@change="onChartTypeChange"
					class="type-select"
					size="default"
				>
					<el-option
						v-for="item in chartTypes.filter((item) =>
							selectedChartModel === 'line' ? item.value !== 'ternary' : true
						)"
						:key="item.value"
						:label="item.label"
						:value="item.value"
					/>
				</el-select>
			</div>
			<div class="chart-type-selector-right">
				<div class="model-label">模型类型：</div>
				<div class="model-buttons">
					<el-button
						v-for="item in chartModel.filter((item) =>
							selectedChartType === 'ternary' ? item.value !== 'line' : true
						)"
						:key="item.value"
						:type="selectedChartModel === item.value ? 'primary' : 'default'"
						@click="onChartModelChange(item.value)"
						class="model-btn"
						size="default"
						:loading="isLoading"
					>
						{{ item.label }}
					</el-button>
				</div>
			</div>
		</div>

		<!-- 主要内容区域 -->
		<div class="div-container">
			<div class="left" :style="{ width: leftPanelWidth + 'px' }">
				<!-- 动态加载对应的左侧组件 -->
				<component
					:is="isComponent"
					:isLoading="isLoading"
					:type="selectedChartType"
					:key="timer"
					@on-submit="onSubmit"
				/>
			</div>

			<!-- 可拖动的分隔条 -->
			<div
				class="resize-handle"
				@mousedown="startDrag"
				:class="{ dragging: isDragging }"
			>
				<div class="resize-indicator">
					<div class="resize-dots">
						<div class="dot"></div>
						<div class="dot"></div>
						<div class="dot"></div>
					</div>
				</div>
			</div>

			<div class="right">
				<!-- 右侧结果展示组件 -->
				<ResultViews
					:isLoading="isLoading"
					:resultImage="resultImage"
					:resultData="resultData"
					:resultType="resultType"
					:title="resultTitle"
					:key="timer"
				/>
			</div>
		</div>
	</div>
</template>

<style scoped lang="scss">
.line-graph-container {
	height: 100%;
	display: flex;
	flex-direction: column;
	background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
	overflow: hidden;
}

.chart-type-selector {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 20px 24px;
	background: rgba(255, 255, 255, 0.95);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid rgba(229, 231, 235, 0.8);
	box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
	position: relative;
	z-index: 100;
	transition: all 0.3s ease;

	&:hover {
		box-shadow: 0 6px 25px rgba(0, 0, 0, 0.12);
	}

	.chart-type-selector-left {
		display: flex;
		align-items: center;
		gap: 16px;

		.selector-label {
			display: flex;
			align-items: center;
			gap: 8px;
			font-size: 16px;
			font-weight: 600;
			color: #1f2937;
			letter-spacing: 0.3px;
			text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);

			.chart-icon {
				width: 20px;
				height: 20px;
				background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
				border-radius: 50%;
				position: relative;
				box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);

				&::before {
					content: '';
					position: absolute;
					top: 50%;
					left: 50%;
					width: 10px;
					height: 10px;
					background: white;
					border-radius: 50%;
					transform: translate(-50%, -50%);
				}
			}
		}

		.type-select {
			width: 220px;

			:deep(.el-select__wrapper) {
				border-radius: 10px;
				border: 1px solid #d1d5db;
				box-shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
				transition: all 0.3s ease;
				background: #ffffff;

				&:hover {
					border-color: #3b82f6;
					box-shadow: 0 4px 15px rgba(59, 130, 246, 0.15);
					transform: translateY(-1px);
				}

				&.is-focused {
					border-color: #3b82f6;
					box-shadow:
						0 0 0 3px rgba(59, 130, 246, 0.1),
						0 4px 15px rgba(59, 130, 246, 0.15);
				}
			}

			:deep(.el-select__placeholder) {
				color: #6b7280;
			}

			:deep(.el-input__inner) {
				color: #1f2937;
				font-weight: 500;
			}
		}
	}

	.chart-type-selector-right {
		display: flex;
		align-items: center;
		gap: 16px;

		.model-label {
			font-size: 16px;
			font-weight: 600;
			color: #1f2937;
			letter-spacing: 0.3px;
			text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
		}

		.model-buttons {
			display: flex;
			gap: 8px;

			.model-btn {
				border-radius: 10px;
				font-weight: 600;
				font-size: 14px;
				letter-spacing: 0.3px;
				transition: all 0.3s ease;
				border: 1px solid transparent;
				padding: 8px 16px;

				&.el-button--default {
					background: #ffffff;
					color: #374151;
					border-color: #d1d5db;
					box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);

					&:hover {
						background: #f8fafc;
						border-color: #9ca3af;
						color: #1f2937;
						transform: translateY(-2px);
						box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
					}
				}

				&.el-button--primary {
					background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
					border-color: transparent;
					color: #ffffff;
					font-weight: 600;
					transform: translateY(-1px);
					box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);

					&:hover {
						transform: translateY(-3px);
						box-shadow: 0 6px 20px rgba(59, 130, 246, 0.4);
						background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
						color: #fff;
					}
				}
			}
		}
	}
}

// 主容器布局
.div-container {
	display: flex;
	height: calc(100vh - 85px);
	flex: 1;
	overflow: hidden;
	box-sizing: border-box;

	// 左侧面板
	.left {
		background: rgba(255, 255, 255, 0.95);
		backdrop-filter: blur(10px);
		border-right: 1px solid rgba(229, 231, 235, 0.8);
		display: flex;
		flex-direction: column;
		box-shadow: 4px 0 20px rgba(0, 0, 0, 0.1);
		transition: all 0.3s ease;
		position: relative;
		flex-shrink: 0; // 防止收缩

		&::before {
			content: '';
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			height: 4px;
			background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 100%);
			box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
		}

		&:hover {
			box-shadow: 6px 0 25px rgba(0, 0, 0, 0.12);
		}
	}

	// 可拖动的分隔条
	.resize-handle {
		width: 4px;
		background: rgba(241, 245, 249, 0.8);
		cursor: col-resize;
		position: relative;
		display: flex;
		align-items: center;
		justify-content: center;
		transition: all 0.2s ease;
		flex-shrink: 0;

		&:hover {
			background: rgba(59, 130, 246, 0.1);
			width: 4px;

			.resize-indicator {
				opacity: 1;
				transform: scale(1.2);
			}
		}

		&.dragging {
			background: rgba(59, 130, 246, 0.2);
			width: 4px;

			.resize-indicator {
				opacity: 1;
				transform: scale(1.3);
			}
		}

		.resize-indicator {
			width: 4px;
			height: 40px;
			background: rgba(59, 130, 246, 0.6);
			border-radius: 2px;
			display: flex;
			flex-direction: column;
			align-items: center;
			justify-content: center;
			gap: 4px;
			opacity: 0.6;
			transition: all 0.2s ease;

			.resize-dots {
				display: flex;
				flex-direction: column;
				gap: 2px;

				.dot {
					width: 2px;
					height: 2px;
					background: rgba(255, 255, 255, 0.8);
					border-radius: 50%;
				}
			}
		}

		// 拖动时的全局光标样式
		&.dragging {
			cursor: col-resize;
		}
	}

	// 右侧面板
	.right {
		flex: 1;
		background: rgba(255, 255, 255, 0.9);
		backdrop-filter: blur(10px);
		display: flex;
		flex-direction: column;
		position: relative;
		overflow: hidden;
		box-shadow: inset 2px 0 10px rgba(0, 0, 0, 0.05);

		&::before {
			content: '';
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			height: 4px;
			background: linear-gradient(90deg, #8b5cf6 0%, #ec4899 100%);
			box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
		}
	}
}

// 添加滚动条样式
:deep(::-webkit-scrollbar) {
	width: 8px;
	height: 8px;
}

:deep(::-webkit-scrollbar-track) {
	background: rgba(241, 245, 249, 0.8);
	border-radius: 4px;
	box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
}

:deep(::-webkit-scrollbar-thumb) {
	background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
	border-radius: 4px;
	box-shadow: 0 2px 6px rgba(59, 130, 246, 0.3);

	&:hover {
		background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
		box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);
	}
}

// 拖动时的全局样式
:global(body.dragging) {
	cursor: col-resize !important;
	user-select: none;

	* {
		cursor: col-resize !important;
		user-select: none;
	}
}

// 添加一些微妙的动画效果
.chart-type-selector {
	&::after {
		content: '';
		position: absolute;
		bottom: 0;
		left: 0;
		right: 0;
		height: 1px;
		background: linear-gradient(
			90deg,
			transparent 0%,
			rgba(59, 130, 246, 0.3) 50%,
			transparent 100%
		);
		transform: scaleX(0);
		transition: transform 0.3s ease;
	}

	&:hover::after {
		transform: scaleX(1);
	}
}
</style>
